﻿package com.android.helix;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;

public final class Loader {
	Loader(Context aContext){
		mContext = aContext;
	}
	public static int loadTexture(String aPath){
		if  (mContext == null) {
			return 0;
		}
		if (mTextures.containsKey(aPath) == true){
			return mTextures.get(aPath);
		}

		InputStream is;
    	Bitmap bitmap = null;
    	try {
    		is = mContext.getAssets().open(aPath);
    		bitmap = BitmapFactory.decodeStream(is);
    	} catch (IOException e) {
			Log.e(Utils.TAG, "Could not load texture: " + aPath);
		}
    	
		int[] textures = new int[1];
		

		GLES20.glGenTextures(1, textures, 0);
		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
		GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
		GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
		GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
		GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);		
		GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);		
    	bitmap.recycle();
    	
    	mTextures.put(aPath, textures[0]);
		return textures[0];
	}
	
	public static IndexVertexData loadIboVbo(String aPath, int aIndexDataSize, int aVertexDataSize){
		
		if  (mContext == null) {
			return null;
		}
		if (mIboVboMap.containsKey(aPath) == true){
			return mIboVboMap.get(aPath);
		}

		DataInputStream dis;
		IntBuffer iboVbo = IntBuffer.allocate(2);
		ByteBuffer indexBuffer = ByteBuffer.allocateDirect(aIndexDataSize).order(ByteOrder.BIG_ENDIAN);
		ByteBuffer vertexBuffer = ByteBuffer.allocateDirect(aVertexDataSize).order(ByteOrder.BIG_ENDIAN);
		
		indexBuffer.position(0);
		vertexBuffer.position(0);
		
    	try {
    		dis = new DataInputStream (mContext.getAssets().open(aPath));

    		//read index data
    		for (int i = 0; i < aIndexDataSize; i++){
    			indexBuffer.put(dis.readByte());
    		}
    		
    		// read points
    		for (int i = 0; i < aVertexDataSize; i++){
    			vertexBuffer.put(dis.readByte());
    		}
    	} catch (IOException e) {
			Log.e(Utils.TAG, "Could not load mesh data: " + aPath);
		}

    	indexBuffer.position(0);
    	vertexBuffer.position(0);
    	
		GLES20.glGenBuffers(2, iboVbo);
		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, iboVbo.get(0));
		GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, aIndexDataSize, indexBuffer, GLES20.GL_STATIC_DRAW);
		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, iboVbo.get(1));
		GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, aVertexDataSize, vertexBuffer, GLES20.GL_STATIC_DRAW);
    	
		IndexVertexData indexVertexData = new IndexVertexData(iboVbo, indexBuffer, vertexBuffer);
		mIboVboMap.put(aPath, indexVertexData);
		return indexVertexData;
	}
	
	private static HashMap<String, Integer> mTextures = new HashMap<String, Integer>();
	private static HashMap<String, IndexVertexData> mIboVboMap = new HashMap<String, IndexVertexData>();
	private static Context mContext = null;
}

class IndexVertexData{
	IndexVertexData(IntBuffer aIboVbo, ByteBuffer aIndexBuffer, ByteBuffer aVertexBuffer){
		mIboVbo = aIboVbo;
		mIndexBuffer = aIndexBuffer;
		mVertexBuffer = aVertexBuffer;
	}
	IntBuffer mIboVbo;
	ByteBuffer mIndexBuffer;
	ByteBuffer mVertexBuffer;
}
